


import { engine } from "../../engine/engine";
import { BehaviorTree } from "./BehaviorTree";
import { EStatus } from "./common/EnumType";

class TreeRunner {
    tree: BehaviorTree
    call: Function;
}

export default class BehaviorTreeMgr  {
    private static ins: BehaviorTreeMgr;
    static instance(): BehaviorTreeMgr {
        if (!this.ins) {
            this.ins = new BehaviorTreeMgr()
        }
        return this.ins;
    }
    protected trees: TreeRunner[] = []

    protected buffer: TreeRunner[] = []
    protected del: TreeRunner[] = []

    /**
     * 执行一个tree。
     * @param tree 
     * @param callback 
     * @returns 
     */
    put(tree: BehaviorTree, callback: Function) {
        let index = this.getIndex(tree)
        if (index >= 0) {
            engine.log('行为树已经在执行了')
            return;
        }
        let obj = this.buffer.length > 0 ? this.buffer.shift() : new TreeRunner();
        obj.tree = tree;
        obj.call = callback;

        tree.setEndCallback((status: EStatus) => {
            this.del.push(obj)
            engine.log('行为树')
            obj.call()
        })
        engine.log('行为树开始')
        this.trees.push(obj)
    }

    private getIndex(tree: BehaviorTree) {
        for (let index = 0; index < this.trees.length; index++) {
            const element = this.trees[index];
            if (element.tree === tree) {
                return index;
            }
        }
        return -1;
    }

    /**
     * 主动删除一个正在执行的tree
     * @param tree 
     */
    remove(tree: BehaviorTree) {
        let index = this.getIndex(tree)
        if (index >= 0) {
            this.buffer.push(this.trees[index])
            this.trees.splice(index, 1)
        }
    }

    /**
     * 更新正在执行的tree
     * @param dt 
     */
    tick(dt?: number) {
        if (this.trees.length > 0) {
            for (let index = 0; index < this.trees.length; index++) {
                const element = this.trees[index];
                element.tree.tick()
            }
            if (this.del.length > 0) {
                engine.log(' 有需要删除的行为  ', this.del.length)
            }
            while (this.del.length > 0) {
                let obj = this.del.shift();
                let index = this.trees.indexOf(obj)
                if (index >= 0) {
                    this.trees.splice(index, 1)
                    this.buffer.push(obj)
                }
            }
        }
    }

    clear() {
        this.buffer.length = 0
        this.trees.length = 0;
    }

}